package com.cs.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cs.es.ProdEs;
import com.cs.service.SearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SearchServiceImpl implements SearchService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;


    /**
     * 通过分组标签的id查询商品
     *
     * @param page
     * @param size
     * @param tagId
     * @return
     */
    @Override
    public Page<ProdEs> prodListByTagId(Integer page, Integer size, Long tagId) {
        TermQueryBuilder tagList = QueryBuilders.termQuery("tagList", tagId);
        return queryProdList(page, size, tagList, null, 0);

    }

    /**
     * 通过关键字查询商品
     * 排序
     * 分页
     * 高亮
     *
     * @param page
     * @param size
     * @param keywords
     * @param sort
     * @return
     */
    @Override
    public Page<ProdEs> searchProdPage(Integer page, Integer size, String keywords, Integer sort) {
        MatchQueryBuilder matchQuery=null;
        if(StringUtils.hasText(keywords)){
            matchQuery = QueryBuilders.matchQuery("prodName", keywords);
        }
        return queryProdList(page,size,matchQuery,keywords,sort);
    }

    /**
     * 查询的方法
     * @param page
     * @param size
     * @param queryBuilder
     * @param keywords
     * @param sort
     * @return
     */
    private Page<ProdEs> queryProdList(Integer page, Integer size, QueryBuilder queryBuilder, String keywords, Integer sort){
        //组装条件
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //排序
        SortBuilder sortBuilder = getSort(sort);
        nativeSearchQueryBuilder.withQuery(queryBuilder).withPageable(PageRequest.of(page,size)
        ).withSort(sortBuilder);

        if(StringUtils.hasText(keywords)){
            //组装条件
            HighlightBuilder.Field field=new HighlightBuilder.Field("prodName");
            field.preTags("<span style='color:red'>");
            field.postTags("</span>");
            nativeSearchQueryBuilder.withHighlightFields(field);
        }
        NativeSearchQuery build = nativeSearchQueryBuilder.build();
        //查询的结果
        SearchHits<ProdEs> esSearchHits = elasticsearchRestTemplate.search(build, ProdEs.class);
        //返回的所需的集合对象
        ArrayList<ProdEs> prodEsList = new ArrayList<>();
        //循环
        esSearchHits.forEach(esSearchHit->{
            ProdEs prodEs = esSearchHit.getContent();
            List<String> prodNames = esSearchHit.getHighlightField("prodName");
            //判断是否是高亮查询
            if(!CollectionUtils.isEmpty(prodNames)){
                String highName = prodNames.get(0);
                if(StringUtils.hasText(highName)){
                    prodEs.setProdName(highName);
                }
            }
            prodEsList.add(prodEs);
        });

        //返回的对象
        Page<ProdEs> prodEsPage = new Page<>(page+1,size);
        //总条数
        prodEsPage.setTotal(prodEsList.size());
        prodEsPage.setRecords(prodEsList);
        return prodEsPage;
    };



    /**
     * 排序的方法
     *
     * @param sort
     * @return
     */
    private SortBuilder getSort(Integer sort) {
        switch (sort) {
            case 0:
                // 好评排序
                return SortBuilders.fieldSort("positiveRating").order(SortOrder.DESC);
            case 1:
                // 销量排序
                return SortBuilders.fieldSort("soldNum").order(SortOrder.DESC);
            case 2:
                // 价格排序
                return SortBuilders.fieldSort("price").order(SortOrder.ASC);
            default:
                throw new IllegalArgumentException("排序字段不允许");
        }

    }
}
